import * as THREE from "three";
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader"; 
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"; 
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"; 
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
import { CSS2DRenderer, CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer';

class Base3d {
    constructor(selector, measure, status) {
        this.container = document.querySelector(selector)
        this.camera;
        this.scene = new THREE.Scene();
        this.renderer;
        this.loadingManager = new THREE.LoadingManager()
        this.labelRenderer = new CSS2DRenderer(),
        this.raycaster = new THREE.Raycaster()
        this.mouse = new THREE.Vector2()
        this.init();
        this.animate();
        // 动态参数值
        this.measure = measure;
        this.status = status;
        this.water = false;
        this.isJtan; // 急停按钮
        this.isJsxh; // 浸水信号
        this.isXtygz; // 系统有故障
        // 保存旧材质
        this.oldYhywMat;
        this.oldEhywMat;
        this.oldSsllMat;
        this.oldWaterMat;
        // 新材质
        this.redMat = new THREE.MeshBasicMaterial({ color: 0xff0000 })
        this.yellowMat = new THREE.MeshBasicMaterial({ color: 0xff6600 })
        this.greenMat = new THREE.MeshBasicMaterial({ color: 0x22652A })
        this.grayMat = new THREE.MeshBasicMaterial({ color: 0x333333 })
        this.newWaterMat = new THREE.MeshPhysicalMaterial({color:0x22652A, map: new THREE.TextureLoader().load('map.jpg') });
    }
 
    init() {
        this.initCamera();
        this.initRenderer();
        this.setEnvMap();
        this.initControls();
        this.addGltf(this.modelName);
        this.loading()
        this.rayCaster()
        window.addEventListener('resize', this.onWindowReset.bind(this))
        console.log(this.measure , this.status)
    }

    initMeasureData(){
        let that = this
        var xhr = new XMLHttpRequest();
        xhr.open("GET", "src/measureData.json", true);
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4 && xhr.status === 200) {
                var data = JSON.parse(xhr.responseText);
                // 对返回的JSON数据进行处理
                // console.log(data.rows)
                data.rows.forEach(e => {
                    if(e.desc === '一号液位'){
                        that.creatLabel('Yhyw', e.desc, e.value)
                    }
                    if(e.desc === '二号液位'){
                        that.creatLabel('Ehyw', e.desc, e.value)
                    }
                    if(e.desc === '总压力'){
                        that.creatLabel('Zyl', e.desc, e.value)
                    }
                    if(e.desc === '五号泵压力'){
                        that.creatLabel('Whbyl', e.desc, e.value)
                    }
                    if(e.desc === '瞬时流量'){
                        that.creatLabel('Ssll', e.desc, e.value)
                    }
                });
            }
        };
        xhr.send();
    }

    initStatusData(){
        let that = this
        var xhr = new XMLHttpRequest();
        xhr.open("GET", "src/statusData.json", true);
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4 && xhr.status === 200) {
                var data = JSON.parse(xhr.responseText);
                // 对返回的JSON数据进行处理
                // console.log(data.rows)
                data.rows.forEach(e => {
                    /* -----------------------其他--------------------*/
                    // 急停按钮
                    if(e.name === "Tbdzsbf.Jtan"){
                        // 0正常灰色，1急停红色
                        if(e.value === 1){
                            document.getElementById('Jtan').style.backgroundColor = 'red'
                        }else{
                            document.getElementById('Jtan').style.backgroundColor = 'gray'
                        }
                        
                    }
                    // 浸水信号
                    if(e.name === "Tbdzsbf.Jsxh"){
                        // 前端显示，实时显示，0绿色1红色（字体提示，泵房浸水）
                        if(e.value === 1){
                            document.getElementById('Jsxh').style.backgroundColor = 'red'
                        }else{
                            document.getElementById('Jsxh').style.backgroundColor = 'gray'
                        }
                    }
                    // 系统有故障
                    if(e.name === "Tbdzsbf.Xtygz"){
                        // 前端显示，实时显示，0绿色1红色（字体提示，泵房浸水）
                        if(e.value === 1){
                            document.getElementById('Xtygz').style.backgroundColor = 'red'
                        }else{
                            document.getElementById('Xtygz').style.backgroundColor = 'gray'
                        }
                    }
                    // 五号泵检修
                    if(e.name === "Tbdzsbf.Whbjx"){
                        // 1检修0启用  前端显示，泵体上显示检修字样 红色字体黄色背景
                        if(e.value === 1){
                            that.creatWarring()
                        }
                    }
                    /* -----------------------五号泵--------------------*/
                    // 五号泵工频运行信号反馈
                    if(e.name === "Tbdzsbf.Whbgpyxxhfk"){
                        // 0灰色1绿色
                        const model = that.scene.getObjectByName('大电机')
                        if(e.value === 0){
                            model.material = that.grayMat
                            that.scene.traverse(obj => {
                                if(obj.isMesh && obj.name.includes('管道-流动')){
                                    obj.material = that.newWaterMat
                                }
                            })
                        }else if(e.value === 1){
                            model.material = that.greenMat
                            that.creatLabel('大电机top', '提示', '工频运行')
                        }
                    }
                    // 五号泵工频故障信号反馈
                    if(e.name === "Tbdzsbf.Whbgpgzxhfk"){
                        // 0灰色1红色
                        const model = that.scene.getObjectByName('大电机')
                        if(e.value === 0){
                            model.material = that.grayMat
                            that.scene.traverse(obj => {
                                if(obj.isMesh && obj.name.includes('管道-流动')){
                                    obj.material = that.newWaterMat
                                }
                            })
                        }else if(e.value === 1){
                            model.material = that.redMat
                            that.creatLabel('大电机top', '提示', '工频故障')
                        }
                    }
                    // 五号泵变频器运行反馈
                    if(e.name === "Tbdzsbf.Whbbpqgzfk"){
                        // 0灰色1黄色
                        const model = that.scene.getObjectByName('大电机')
                        if(e.value === 0){
                            model.material = that.grayMat
                        }else if(e.value === 1){
                            model.material = that.yellowMat
                            that.creatLabel('大电机top', '提示', '变频运行')
                        }
                    }
                    // 五号泵变频器故障反馈
                    if(e.name === "Tbdzsbf.Whbgpyxxhfk"){
                        // 0灰色1红色
                        const model = that.scene.getObjectByName('大电机')
                        if(e.value === 0){
                            model.material = that.grayMat
                        }else if(e.value === 1){
                            model.material = that.redMat
                            that.creatLabel('大电机top', '提示', '变频故障')
                        }
                    }
                    /* -----------------------------------------------*/
                    // 一号液位高报警
                    if(e.name === "Tbdzsbf.Yhywgbj"){
                        // 0灰色1红色
                        const model = that.scene.getObjectByName('Yhyw')
                        if(e.value === 0){
                            model.material = that.grayMat
                        }else if(e.value === 1){
                            model.material = that.redMat
                        }
                    }
                    // 一号液位低报警
                    if(e.name === "Tbdzsbf.Yhywdbj"){
                        // 0灰色1黄色
                        const model = that.scene.getObjectByName('Yhyw')
                        if(e.value === 0){
                            model.material = that.grayMat
                        }else if(e.value === 1){
                            model.material = that.yellowMat
                        }
                    }
                    // 二号液位高报警
                    if(e.name === "Tbdzsbf.Ehywgbj"){
                        // 0灰色1红色
                        const model = that.scene.getObjectByName('Ehyw')
                        if(e.value === 0){
                            model.material = that.grayMat
                        }else if(e.value === 1){
                            model.material = that.redMat
                        }
                    }
                    // 二号液位低报警
                    if(e.name === "Tbdzsbf.Ehywdbj"){
                        // 0灰色1黄色
                        const model = that.scene.getObjectByName('Ehyw')
                        if(e.value === 0){
                            model.material = that.grayMat
                        }else if(e.value === 1){
                            model.material = that.yellowMat
                        }
                    }   
                    // 五号泵压力高报警
                    if(e.name === "Tbdzsbf.Whbylgbj"){
                        // 0灰色1绿色
                        const model = that.scene.getObjectByName('Whbyl')
                        if(e.value === 0){
                            model.material = that.grayMat
                        }else if(e.value === 1){
                            model.material = that.greenMat
                        }
                    }
                    // 五号泵压力低报警
                    if(e.name === "Tbdzsbf.Whbyldbj"){
                        // 0灰色1绿色
                        const model = that.scene.getObjectByName('Whbyl')
                        if(e.value === 0){
                            model.material = that.grayMat
                        }else if(e.value === 1){
                            model.material = that.yellowMat
                        }
                    }
                    // 总压力高报警
                    if(e.name === "Tbdzsbf.Zylgbj"){
                        // 0灰色1绿色
                        const model = that.scene.getObjectByName('Zyl')
                        if(e.value === 0){
                            model.material = that.grayMat
                        }else if(e.value === 1){
                            model.material = that.greenMat
                        }
                    }
                    // 总压力低报警
                    if(e.name === "Tbdzsbf.Zyldbj"){
                        // 0灰色1绿色
                        const model = that.scene.getObjectByName('Zyl')
                        if(e.value === 0){
                            model.material = that.grayMat
                        }else if(e.value === 1){
                            model.material = that.yellowMat
                        }
                    }
                });
            }
        };
        xhr.send();
    }

    initCamera() {
        this.camera = new THREE.PerspectiveCamera(
            45,
            window.innerWidth / window.innerHeight,
            0.01,
            100000
        );
        this.camera.position.set(-20, 20, -20)
    }
 
    initRenderer() {
        this.renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true, logarithmicDepthBuffer: true });
        this.renderer.setPixelRatio(window.devicePixelRatio);
        this.renderer.setSize(window.innerWidth, window.innerHeight);
        this.container.appendChild(this.renderer.domElement);
        this.renderer.shadowMap.enabled = true

        this.labelRenderer.setSize( window.innerWidth, window.innerHeight );
        this.container.appendChild(this.labelRenderer.domElement);
        this.labelRenderer.domElement.style.position = 'absolute';
        this.labelRenderer.domElement.style.bottom = '0px';
        this.labelRenderer.domElement.style.left = '0px';
        this.labelRenderer.domElement.style.pointerEvents = 'none'
    }
 
    setEnvMap() {
        new RGBELoader().load('HDR.hdr', (texture) => {
            texture.mapping = THREE.EquirectangularRefractionMapping;
            this.renderer.toneMapping = THREE.ACESFilmicToneMapping;
            this.renderer.toneMappingExposure = 4;
            this.scene.background = new THREE.Color(0x041035) //设置背景色
            this.scene.environment = texture;
        });
    }
 
    render() {
        this.controls.update()
        this.renderer.render(this.scene, this.camera)
        this.labelRenderer.render(this.scene,this.camera)
        this.renderer.precision = 'highp'
        this.scene.traverse(obj => {
            if(obj.isMesh && obj.name.includes('管道-流动')){
                obj.material.map.offset.y += 0.001
            }
        })
    }
 
    animate() {
        this.renderer.setAnimationLoop(this.render.bind(this))
    }
 
    initControls() {
        this.controls = new OrbitControls(this.camera, this.renderer.domElement)
        this.controls.update()
        // this.controls.minPolarAngle = Math.PI / 4;
        // this.controls.maxPolarAngle = Math.PI / 2 - 0.1;
    }

    addGltf() {
        const dracoLoader = new DRACOLoader();
        dracoLoader.setDecoderPath("/draco/");
        return new Promise(() => {
            new GLTFLoader(this.loadingManager).setDRACOLoader(dracoLoader).load('modelD.glb', gltf => {
                this.model = gltf.scene;
                this.scene.add(this.model);
                this.oldYhywMat = this.scene.getObjectByName('Yhyw').material
                this.oldEhywMat = this.scene.getObjectByName('Ehyw').material
                this.oldSsllMat = this.scene.getObjectByName('Ssll').material
                this.oldWaterMat = this.scene.getObjectByName('管道流动').material
                this.initMeasureData()
                this.initStatusData()
            })
        })

    }

    creatLabel(name,desc,value,color=null) {
        const labelDiv = document.createElement('div');
        labelDiv.className = "labeldiv"
        labelDiv.innerHTML = `
            <div>${desc}: ${value}</div>
        `
        const labeldiv = new CSS2DObject(labelDiv);
        const pos = this.scene.getObjectByName(name).position
        labeldiv.position.set(pos.x  ,pos.y + .5 , pos.z)
        if(color){
            labelDiv.style.color = color
            labelDiv.style.backgroundColor = color
            labelDiv.style.border = color
        }
        // labeldiv.name = e.name
        this.scene.add(labeldiv);
    }

    creatWarring() {
        const labelDiv = document.createElement('div');
        labelDiv.className = "labelWarring"
        labelDiv.innerHTML = `
            <div>检修</div>
        `
        const labeldiv = new CSS2DObject(labelDiv);
        const pos = this.scene.getObjectByName('大电机').position
        labeldiv.position.set(pos.x  ,pos.y + .5 , pos.z)
        // labeldiv.name = e.name
        this.scene.add(labeldiv);
    }
    rayCaster() {
        window.addEventListener('mousemove', event=>{
            this.mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
            this.mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;
            this.raycaster.setFromCamera(this.mouse, this.camera);
            let intersects = this.raycaster.intersectObjects(this.scene.children);
            if(intersects.length > 0 && intersects[0].object.isMesh){
                this.scene.children.map(e=>{
                    if(e.type == 'Object3D' && intersects[0].object.name.includes(e.name)){
                        e.visible = true
                    }else if(e.type == 'Object3D'){
                        e.visible = false
                    }
                })
            }
        });
    }

    onWindowReset() {
        this.camera.aspect = window.innerWidth / window.innerHeight;
        this.camera.updateProjectionMatrix();
        this.renderer.setSize(window.innerWidth, window.innerHeight);
        this.labelRenderer.setSize(window.innerWidth, window.innerHeight);
    }

    loading(){
        // 加载进度
        var jindu_text_con = document.getElementById('jindu-text-con');
        var jindu_text = document.getElementById('jindu-text');
        var jindu = document.getElementById('jindu');
        
        let i = 0
        const tim = setInterval(() => { 
            if(i < 89){
                i += Math.random()
                jindu_text.innerText = Math.floor(i) + '%'
                jindu.style.width = Math.floor(i) + '%'
            }else{
                clearInterval(tim)
            }
        }, 300);
        this.loadingManager.onProgress = (url,itemsLoaded,itemsTotal)=>{
            let _onProgress = Math.floor(itemsLoaded / itemsTotal *100)
            if (_onProgress == 100) {
                jindu_text_con.style.display = 'none'
            }
        }
    }

}
 
export default Base3d